package com.cskaoyan.javase.oop1._9block._3static;

/**
 * @description: 静态代码块
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * 静态代码块: 和构造代码块一样,静态代码块也是定义在成员位置的代码块
 * 语法: static {}
 * 作用: 静态代码块随着类加载而被执行,可以认为静态代码块是一个在类加载过程中自动执行的静态方法
 *      它经常用于给静态成员变量赋值
 *
 * 总结给静态成员变量赋值的方式:
 *      类加载过程中:
 *      1,默认初始化,具有默认值
 *      2,显式赋值
 *      3,静态代码块
 *      严格来说,类名点赋值也算,但是这种方式赋值它的赋值一定是正确的,我们不讨论
 *      创建对象过程中:
 *      1,构造代码块
 *      2,构造器
 *      创建对象之后:
 *      1,用成员方法赋值
 *  重点研究类加载时期的赋值方式:
 *      1,默认初始化,具有默认值是第一步
 *      2,显式赋值和静态代码块也是按照代码的书写顺序执行,谁在代码的上面谁就先执行
 *  当然，仍然建议将静态代码块写在变量声明和显式赋值的下面，避免造成一些不必要的麻烦
 *
 *
 * > 一些细节问题
 * 1. 静态代码块可以近似看成一个静态成员方法，所以不能在里面调用非静态（包括this和super）
 * 2. 当需要使用复杂的代码给静态成员变量赋值时，可以使用静态代码块
 *    - 但如果仅仅是简单的赋值，直接显式赋值即可
 * 3. 构造代码块可以给静态成员变量赋值，静态代码块却不能给普通成员代码块赋值
 *    - 类加载在创建对象之前进行，此时没有对象，肯定没有办法赋值
 *
 * 4. 静态代码块和静态成员变量显式赋值的执行顺序，是由类加载的机制保证的
 *    - 类加载的具体流程，我们后面会学习，不必着急
 *
 * 5. 静态代码块也经常被用来测试类加载的顺序
 *    - **一个类的静态代码块如果没有被执行，至少说明它没有被完全类加载**（可能类加载流程走了一半）
 *
 * 类加载的流程: 加载 ---> 链接(连接) ---> 初始化
 * 初始化这个步骤主要是完成静态成员变量的声明初始化,还有就是执行静态代码块
 *
 *
 */
public class Demo {
    public static void main(String[] args) {
        System.out.println(Student.age);
    }
}

class Student {

    static int age = 18;
    String name;

    static {
        Student s = new Student();
        System.out.println(s.name);
        age = 28;
        System.out.println("Student类加载了");
    }

}